using System;
using System.IO;
using System.Threading;

namespace Tail
{
	/// <summary>
	/// Summary description for Tail.
	/// </summary>
	public class Tail
	{
		private String filename;
		private Thread thread;
		private bool running = true;

		private System.Collections.Hashtable configParams = new System.Collections.Hashtable();

		private bool continousTail = false;
		private int historyCount = 500;

		public Tail(System.Collections.Hashtable configParams)
		{
			this.continousTail = configParams["f"]!=null;
			if (configParams["lines"]!=null)
				this.historyCount =  Int32.Parse(((String)configParams["lines"]));
			this.filename = (String)configParams["file"];
			if (filename!=null && !filename.Equals("") && !System.IO.File.Exists(filename)){
				System.Windows.Forms.MessageBox.Show("Could not locate file \"" + filename + "\"");
			}
			Console.Write("Processing ");
			if (continousTail)
				Console.Write("-f ");
			if (configParams["lines"]!=null)
				Console.Write(configParams["lines"] + " ");
			Console.WriteLine(filename);
			thread = new Thread(new ThreadStart(run));
			thread.Start();
		}

		public void run(){
			StreamReader fileReader = null;
			try
			{
				FileStream fileStream = new FileStream(filename,FileMode.Open,FileAccess.Read,FileShare.ReadWrite,1024,true);				
				fileStream.Seek(Math.Max(0,fileStream.Length-historyCount),SeekOrigin.Begin);				
				fileReader = new StreamReader(fileStream);
				while (running) 
					try
					{				
						Thread.Sleep(20);
						Console.Write(fileReader.ReadToEnd());
						if (!continousTail)
							running = false;
					}
					catch (ThreadInterruptedException tie)
					{
						Thread.Sleep(50);
					}
					catch (Exception e)
					{
						running = false;
					}
			}
			catch (Exception e)
			{
				Console.WriteLine(e.StackTrace);
			}
			finally{
				if (fileReader!=null)
					fileReader.Close();
			}
		}


		public static void Main()
		{
			if (Environment.GetCommandLineArgs().Length>1) 
			{
				System.Collections.Hashtable configParams = CommandParser.parse(Environment.GetCommandLineArgs());
				if (configParams!=null)
				{
					new Tail(configParams);
					return;
				}
			}
			Console.WriteLine("Usage : tail <switch> file");
			Console.WriteLine("Switches : ");
			Console.WriteLine("-f : continous tail");
			Console.WriteLine("<lines> : history count to show");
		}

	}
}
